<!doctype html>
<html>
<head>
  <title>CodeMirror 2: Ruby mode</title>
  <link rel="stylesheet" href="../../lib/codemirror.css">
  <script src="../../lib/codemirror.js"></script>
  <script src="ruby.js"></script>
  <link rel="stylesheet" href="../../theme/default.css">
  <style>
    .CodeMirror {
      border-top: 1px solid black;
      border-bottom: 1px solid black;
    }

    .cm-s-default span.cm-arrow {
      color: red;
    }
  </style>
  <link rel="stylesheet" href="../../css/docs.css">
</head>
<body>
<h1>CodeMirror 2: Ruby mode</h1>

<form><textarea id="code" name="code">
  # Code from http://sandbox.mc.edu/~bennet/ruby/code/poly_rb.html
  #
  # This program evaluates polynomials. It first asks for the coefficients
  # of a polynomial, which must be entered on one line, highest-order first.
  # It then requests values of x and will compute the value of the poly for
  # each x. It will repeatly ask for x values, unless you the user enters
  # a blank line. It that case, it will ask for another polynomial. If the
  # user types quit for either input, the program immediately exits.
  #

  #
  # Function to evaluate a polynomial at x. The polynomial is given
  # as a list of coefficients, from the greatest to the least.
  def polyval(x, coef)
  sum = 0
  coef = coef.clone # Don't want to destroy the original
  while true
  sum += coef.shift # Add and remove the next coef
  break if coef.empty? # If no more, done entirely.
  sum *= x # This happens the right number of times.
  end
  return sum
  end

  #
  # Function to read a line containing a list of integers and return
  # them as an array of integers. If the string conversion fails, it
  # throws TypeError. If the input line is the word 'quit', then it
  # converts it to an end-of-file exception
  def readints(prompt)
  # Read a line
  print prompt
  line = readline.chomp
  raise EOFError.new if line == 'quit' # You can also use a real EOF.

  # Go through each item on the line, converting each one and adding it
  # to retval.
  retval = [ ]
  for str in line.split(/\s+/)
  if str =~ /^\-?\d+$/
  retval.push(str.to_i)
  else
  raise TypeError.new
  end
  end

  return retval
  end

  #
  # Take a coeff and an exponent and return the string representation, ignoring
  # the sign of the coefficient.
  def term_to_str(coef, exp)
  ret = ""

  # Show coeff, unless it's 1 or at the right
  coef = coef.abs
  ret = coef.to_s unless coef == 1 && exp > 0
  ret += "x" if exp > 0 # x if exponent not 0
  ret += "^" + exp.to_s if exp > 1 # ^exponent, if > 1.

  return ret
  end

  #
  # Create a string of the polynomial in sort-of-readable form.
  def polystr(p)
  # Get the exponent of first coefficient, plus 1.
  exp = p.length

  # Assign exponents to each term, making pairs of coeff and exponent,
  # Then get rid of the zero terms.
  p = (p.map { |c| exp -= 1; [ c, exp ] }).select { |p| p[0] != 0 }

  # If there's nothing left, it's a zero
  return "0" if p.empty?

  # *** Now p is a non-empty list of [ coef, exponent ] pairs. ***

  # Convert the first term, preceded by a "-" if it's negative.
  result = (if p[0][0] < 0 then "-" else "" end) + term_to_str(*p[0])

  # Convert the rest of the terms, in each case adding the appropriate
  # + or - separating them.
  for term in p[1...p.length]
  # Add the separator then the rep. of the term.
  result += (if term[0] < 0 then " - " else " + " end) +
  term_to_str(*term)
  end

  return result
  end

  #
  # Run until some kind of endfile.
  begin
  # Repeat until an exception or quit gets us out.
  while true
  # Read a poly until it works. An EOF will except out of the
  # program.
  print "\n"
  begin
  poly = readints("Enter a polynomial coefficients: ")
  rescue TypeError
  print "Try again.\n"
  retry
  end
  break if poly.empty?

  # Read and evaluate x values until the user types a blank line.
  # Again, an EOF will except out of the pgm.
  while true
  # Request an integer.
  print "Enter x value or blank line: "
  x = readline.chomp
  break if x == ''
  raise EOFError.new if x == 'quit'

  # If it looks bad, let's try again.
  if x !~ /^\-?\d+$/
  print "That doesn't look like an integer. Please try again.\n"
  next
  end

  # Convert to an integer and print the result.
  x = x.to_i
  print "p(x) = ", polystr(poly), "\n"
  print "p(", x, ") = ", polyval(x, poly), "\n"
  end
  end
  rescue EOFError
  print "\n=== EOF ===\n"
  rescue Interrupt, SignalException
  print "\n=== Interrupted ===\n"
  else
  print "--- Bye ---\n"
  end
</textarea></form>
<script>
  var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
    mode:"text/x-ruby",
    tabMode:"indent",
    matchBrackets:true,
    indentUnit:4
  });
</script>

<p><strong>MIME types defined:</strong> <code>text/x-ruby</code>.</p>

<p>Development of the CodeMirror Ruby mode was kindly sponsored
  by <a href="http://ubalo.com/">Ubalo</a>, who hold
  the <a href="LICENSE">license</a>.</p>

</body>
</html>
